﻿using System;
using System.Collections.Generic;
using Com.PhilChuang.Mobile.Apps.LocationSender.Ui.Views.Impl.Pages;
using Com.PhilChuang.Mobile.Apps.LocationSender.Ui.Views.Impl.ViewModels;
using Com.PhilChuang.Utils;
using Microsoft.Phone.Tasks;

namespace Com.PhilChuang.Mobile.Apps.LocationSender.Ui.Views.Impl.ViewFacades
{
	public class SelectContactsViewFacade : AbstractLocationSenderAppViewFacade<SelectContactsPage, SelectContactsPageViewModel>, ISelectContactsView
	{
		#region Constants
		private const String RECIPIENTS_STRING = "RECIPIENTS_STRING";
		#endregion

		#region Events
		public event Action DoReloadData = delegate { };
		public event Action DoSelectCoordsFormat = delegate { };
		#endregion

		#region Instance Variables
		private PhoneNumberChooserTask myNumberChooserTask;
		private EmailAddressChooserTask myEmailAddressChooserTask;
		#endregion

		#region Properties
		public IList<String> Recipients
		{
			get { return myViewModel.Recipients; }
			set
			{
				if (DoNotAccessViewModel ()) return;
				InvokeSet (val => {
				           	if (DoNotAccessViewModel ()) return;
				           	myViewModel.HasBeenLoaded = true;
				           	myViewModel.Recipients = val;
				           },
				           value);
			}
		}
		#endregion

		#region Constructors
		public SelectContactsViewFacade ()
		{
			Init (false);
		}

		public SelectContactsViewFacade (SelectContactsPage page)
		{
			myPage = page;
			Init (true);
		}

		private void Init (bool wireUp)
		{
			myViewModel = new SelectContactsPageViewModel ();
			myViewModel.IsAssociatedWithViewFacadeAndPage = true;
			myViewModel.HasBeenLoaded = false;
			if (wireUp) WireUpPage ();

			myNumberChooserTask = new PhoneNumberChooserTask ();
			myNumberChooserTask.Completed += myNumberChooserTask_Completed;

			myEmailAddressChooserTask = new EmailAddressChooserTask ();
			myEmailAddressChooserTask.Completed += myEmailAddressChooserTask_Completed;
		}
		#endregion

		#region Implementation of IView/ISelectContactsView
		// no methods to implement
		#endregion

		/// <summary>
		/// Unsubscribes view event handlers.
		/// Call base impl as last step.
		/// </summary>
		protected override void UnWirePage ()
		{
			if (myPage == null) return;

			// ISelectContactsView
			myPage.DoSelectCoordsFormat -= FireDoSelectCoordsFormat;

			// SelectContactsPage
			myPage.DoLookUpNumber -= OnDoLookUpNumber;
			myPage.DoLookUpEmail -= OnDoLookUpEmail;

			base.UnWirePage ();
		}

		/// <summary>
		/// Subscribes view event handlers.
		/// Call base impl as first step.
		/// </summary>
		protected override void WireUpPage ()
		{
			if (myPage == null) return;

			base.WireUpPage ();

			// ISelectContactsView
			myPage.DoSelectCoordsFormat += FireDoSelectCoordsFormat;

			// SelectContactsPage
			myPage.DoLookUpNumber += OnDoLookUpNumber;
			myPage.DoLookUpEmail += OnDoLookUpEmail;
		}

		protected override void FireReload ()
		{ DoReloadData (); }

		protected void FireDoSelectCoordsFormat ()
		{ DoSelectCoordsFormat (); }

		private void OnDoLookUpNumber ()
		{
			EnableAllControls (false);
			myNumberChooserTask.Show ();
		}

		private void OnDoLookUpEmail ()
		{
			EnableAllControls (false);
			myEmailAddressChooserTask.Show ();
		}

		private void myNumberChooserTask_Completed (object sender, PhoneNumberResult e)
		{
			if (e.TaskResult == TaskResult.OK)
			{
				var addy = e.PhoneNumber;
				WaitForShownThenBeginInvokeAsync (
					() => {
						myViewModel.RecipientsString += addy+"; ";
						EnableAllControls (true);
					});
			}
			else
			{
				EnableAllControls (true);
			}
		}

		private void myEmailAddressChooserTask_Completed (object sender, EmailResult e)
		{
			if (e.TaskResult == TaskResult.OK)
			{
				var addy = e.Email;
				WaitForShownThenBeginInvokeAsync (
					() =>
					{
						myViewModel.RecipientsString += addy + "; ";
						EnableAllControls (true);
					});
			}
			else
			{
				EnableAllControls (true);
			}
		}

		protected override void FireClosed ()
		{
			myPage.State[RECIPIENTS_STRING] = myViewModel.RecipientsString;
			base.FireClosed ();
		}

		protected override void FireDoClose (object sender, System.ComponentModel.CancelEventArgs e)
		{
			base.FireDoClose (sender, e);
			myPage.State[RECIPIENTS_STRING] = null; // removing it doesn't seem to persist upon the next page load
			myPage.State.Remove (RECIPIENTS_STRING);
		}

		protected override void FireLoadedAndCheckFireReload ()
		{
			base.FireLoadedAndCheckFireReload ();

			// get state about send message pressed
			if (myPage.State.ContainsKey (RECIPIENTS_STRING))
			{
				var recips = (String) myPage.State[RECIPIENTS_STRING];
				myPage.State[RECIPIENTS_STRING] = null; // removing it doesn't seem to persist upon the next page load
				myPage.State.Remove (RECIPIENTS_STRING);
				if (!recips.IsNullOrEmptyOrBlank ())
					myViewModel.RecipientsString = recips;
			}
		}
	}
}
